﻿using PropertyChanged;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestWinform
{

    public class LcPropDefinition
    {
        public string Name { get; set; }
        public string Display { get; set; }
        public string Descr { get; set; }
        public string Format { get; set; }
        public string Category { get; set; }

    }
    public class LcProerptySetTemplate
    {
        public string Name { get; set; }
        public string Display { get; set; }
        public string Descr { get; set; }
        public string ForClass { get; set; }
        public List<LcPropDefinition> Defs { get; } = new List<LcPropDefinition>();

    }


    public class LcProerptySet
    {
        public string Name { get; set; }
        public List<LcPropDefinition> Defs { get; }
        public List<object> Values { get; set; }
    }
    public class LcObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public long Id { get; set; } = -1;
        public LcProerptySet[] ExtProps { get; set; }
        public LcDocument Document { get; set; }

        protected void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
        {
            PropertyChanged?.Invoke(this, eventArgs);
        }
        public void OnPropertyChanged(string propertyName, object before, object after)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public class StyleChangedEventArgs : EventArgs
    {

    }
    public class ElementStyle
    {

    }
    public abstract class LcElement : LcObject
    {

        public event EventHandler<StyleChangedEventArgs> StyleChanged;
        public LcElement Parent { get; set; }
        public ElementStyle Style { get; set; }
        /// <summary>
        /// 运行时样式，如果没有多层次组合，等同于Style
        /// </summary>
        public ElementStyle RuntimeStyle { get; set; }

        public void OnStyleChanged(object sender, StyleChangedEventArgs e)
        {
            this.StyleChanged?.Invoke(sender, e);
        }
        public bool HitTest(object testBox, object Matrix3)
        {
            return true;
        }

    }
    public class ElementCollection : Collection<LcElement>
    {

    }
    public enum Curve2dType
    {
        Line2d,
    }
    public interface ICurve2d
    {
        Curve2dType Type { get; }

    }
    public class Line2d : ICurve2d
    {
        object Start { get; set; }
        object End { get; set; }

        public Curve2dType Type => Curve2dType.Line2d;

        public Line2d() { }
        public Line2d(object start, object end)
        {
            Start = start;
            End = end;
        }
    }
    /// <summary>
    /// 对所有Curve类型元素，进行统一操作
    /// 插件定义新的元素必须从LcCurveElement继承
    /// 当插件无法加载时，直接生成LcCurveElement通用元素
    /// </summary>
    public class LcCurveElement : LcElement
    {
        public virtual List<ICurve2d> Curves { get; } = new List<ICurve2d>();
    }

    public class LcHatch : LcElement
    {

    }
    public class LcTextStyle : LcObject
    {

    }
    public class LcFont
    {
        public string Name { get; set; }
        public Dictionary<uint, LcFontShape> UsedShapes;

        public LcFontShape GetShape(uint unicode)
        {
            //From Cache
            //From Font File
            return null;
        }
    }
    public class LcFontShape
    {
        public string FontName { get; set; }
    }
    public class LcFormatedFontShape
    {
        public bool Bold { get; set; }
        //.......
    }
    public class LcFontManager
    {
        public Dictionary<string, LcFont> UsedFonts;

    }
    public class LcMText : LcElement
    {
        public string Content { get; set; }
        public LcTextStyle TextStyle { get; set; }
    }

    public class LcLine : LcCurveElement
    {
        public Line2d Line { get; }

        public LcLine()
        {
            this.Line = new Line2d();
            this.Curves.Add(this.Line);
        }
        public LcLine(object start, object end)
        {
            this.Line = new Line2d(start, end);
            this.Curves.Add(this.Line);
        }
        public void SetStart(object start)
        {

        }
        public void SetEnd(object end)
        {

        }
    }

    public class LcElementSpace : LcObject
    {
        public event EventHandler ElementChanged;
        public ElementCollection Elements { get; set; }
    }
    public class LcDocument : LcObject
    {
        LcModelSpace ModelSpace;
        List<LcPaperSpace> PaperSpaces;

        List<LcModel3dViewport> Model3dViewports;
        List<LcView3dViewport> View3dViewports;
    }

    public class LcModelSpace: LcElementSpace
    {

    }
    public class LcPaperSpace : LcElementSpace
    {

    }
    /// <summary>
    /// Model3dEditor的视口状态
    /// </summary>
    public class LcModel3dViewport
    {

    }
    /// <summary>
    /// View3dEditor的视口状态
    /// </summary>
    public class LcView3dViewport
    {

    }
    public class LcBlock : LcElementSpace
    {

    }
    public class LcBlockRef : LcElement
    {
    }
    public class LcXref : LcBlock
    {
        LcDocument XrefDocument { get; set; }
        public LcXref()
        {
            // this.Elements = XrefDocument.ModelSpace.Elements;
        }
    }
    public class LcCompositeElement : LcElement
    {
        //组合元素里 每一种元素处理Matrix的方式有差异
        //例如标注缩放以后，文字及标注尺寸都会发生变换
        //例如镜像以后，文字的方向处理不能镜像，否则无法阅读

        public event EventHandler ElementChanged;
        public ElementCollection Elements { get; set; }
    }
    public class LcGroup : LcCompositeElement
    {

    }
    public class LcDimXxx : LcCompositeElement
    {

    }

    /// <summary>
    /// 二维直接组件,具有业务含义，例如防火分区
    /// </summary>
    public class LcDirectComponent : LcCurveElement
    {
        public string Category;
    }
    /// <summary>
    /// 二维组件，具有业务含义，例如示意的二维家具等
    /// </summary>
    public class LcComponent : LcBlock
    {

    }
    public class LcComponentRef : LcElement
    {

    }
    public interface IElement3d
    {
        //三维元素缩放时需要选择是否转换为二维元素，还是选择按各自元素特性缩放
        //三维元素的缩放，需要各种元素自行处理，例如墙缩放基线长度
        //构件门窗，缩放特定的尺寸参数
         List<AssociatePoint> AssociatePoints { get; }
         List<AssociateElement> AssociateElements { get; }
        LcSolid3d[] Solids { get; }
        ICurve3d[] Curve3ds { get; }
    }
    public class AssociatePoint
    {

    }
    public class AssociateElement
    {

    }
    /// <summary>
    /// 直接三维组件，例如墙体
    /// </summary>
    public class LcDirectCompoent3d : LcDirectComponent,IElement3d
    {
        public string Category;
        public List<AssociatePoint> AssociatePoints => throw new NotImplementedException();
        public List<AssociateElement> AssociateElements => throw new NotImplementedException();
        public LcSolid3d[] Solids { get; }
        public ICurve3d[] Curve3ds { get; }

    }

  
    /// <summary>
    /// 三维构件，例如门窗等
    /// </summary>
    public class LcComponent3d : LcComponent
    {
        public string Category;
        //平面曲线存储在Curves里
        /// <summary>
        /// Curves里的曲线是否是投影曲线,门窗都是示意曲线
        /// </summary>
        public bool IsProjectCurve { get; set; }

        /// <summary>
        /// 命名的曲线组，或者对Curves里的曲线分组
        /// </summary>
        public Dictionary<string, List<ICurve2d>> NamedCurves { get; set; }
        public Dictionary<string, ElementStyle> NamedStyles { get; set; }

        /// <summary>
        /// 对于门窗，会根据设计还是展示来确定是DynamicSolid，还是LibrarySolid
        /// </summary>
        public LcSolid3d[] Solids { get; set; }
        public ICurve3d[] Curve3ds { get; set; }

        public object Arguments { get; set; }
    }
    public class LcComponent3dRef : LcElement, IElement3d
    {
        public object Matrix4 { get; set; }
        LcComponent3d Component { get; set; }
        public LcSolid3d[] Solids => Component.Solids;
        public ICurve3d[] Curve3ds => Component.Curve3ds;

        public List<AssociatePoint> AssociatePoints => throw new NotImplementedException();

        public List<AssociateElement> AssociateElements => throw new NotImplementedException();

    }

  
    public interface ISolid3d
    {
    }
    public class Cubic3d : ISolid3d
    {

    }

    public class Resolve3d: ISolid3d
    {

    }
    public class Extrude3d : ISolid3d
    {

    }
    public class Tube3d : ISolid3d
    {

    }

    public class GeometryGroup
    {
        /// <summary>
        /// 例如一个圆柱体，由Top，Bottom及Around三个面组成
        /// </summary>
        public string Name { get; set; }  
        /// <summary>
        /// 组的数据是否在光滑曲面上，Around圆柱面就是光滑曲面
        /// 光滑曲面上的三角面之间的线是可以隐藏的，形成投影图时页不需要
        /// </summary>
        public bool IsSmooth { get; set; }
        public int Start { get; set; }
        public int Count { get; set; }
        public int MaterialIndex { get; set; }

    }
    public class GeometryData
    {
        public double[] Verteics;
        public int[] Indics;
        public GeometryGroup[] Groups;
    }
    public class LcMaterial
    {

    }
   
    public class LcSolid3d
    {
        public GeometryData Geometry { get; set; }
        public LcMaterial Material { get; set; }
        public LcMaterial[] GroupMaterials { get; set; }
        public GeometryData Edge { get; set; }
        public LcMaterial[] EdgeGroupMaterials { get; set; }
        public LcMaterial EdgeMaterial { get; set; }
        public GeometryData Curve { get; set; }
        public LcMaterial[] CurveGroupMaterials { get; set; }
        public LcMaterial CurveMaterial { get; set; }
    }

    public class LcMeshSolid3d : LcSolid3d
    {
        //需要存储Geometry3d Edge3d 等
    }

    public class LcBrepSolid3d : LcSolid3d
    {

    }
    public class ScriptLibrary
    {
        public string FilePath { get; set; }
        //JS,CS,CSDLL
        public string ScriptType { get; set; }
    }
    /// <summary>
    /// 脚本实体，从Javascirpt，C#脚本库或者文件里加载，
    /// </summary>
    public class LcScriptSolid3d : LcSolid3d
    {
        public string FromFile { get; set; }
        public ScriptLibrary FromLibrary { get; set; }
        public string ScriptClass { get; set; }
        public string ScriptSource { get; set; }
        public object Arguments { get; set; }
    }

    public enum Curve3dType
    {
        Line3d
    }
    public interface ICurve3d
    {
        Curve3dType Type { get; }
    }

    public class Line3d : ICurve3d
    {
        public Curve3dType Type =>  Curve3dType.Line3d;
    }
    public class Surface3d
    {

    }
    public class LcFace3d
    {
        public Surface3d Surface { get; set; }
        public List<ICurve3d> Profile { get; set; }
        public List<List<ICurve3d>> Holes { get; set; }
    }
    /// <summary>
    /// 面模型实体，与Revit实体兼容
    /// </summary>
    public class LcFaceSolid3d : LcSolid3d
    {
        public List<LcFace3d> Faces { get; set; }

        //GroupMaterials对于每个Surface的材质
        //EdgeGroupMaterials 对于每个边的材质
    }
}
